package com.runlooker.runer.ui.chat;

import java.lang.ref.WeakReference;
import java.util.LinkedList;

import org.jivesoftware.smack.XMPPException;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Debug;
import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.runlooker.runer.R;
import com.runlooker.runer.cache.ImageCache;
import com.runlooker.runer.cache.ImageCache.ImageCacheParams;
import com.runlooker.runer.entity.ChatMsgEntity;
import com.runlooker.runer.service.XmppService;
import com.runlooker.runer.util.ImageUtil;
import com.runlooker.runer.util.L;

public class ChatAdapter extends BaseAdapter {
	private String tag = ChatAdapter.class.getSimpleName();
	private LinkedList<ChatMsgEntity> list;
	private LayoutInflater mLayoutInflater;
	private XmppService mXmppService;
	private ChatActivity mActivity;
	private ImageCache mImageCache;
	private ImageCacheParams mImageCacheParams;

	public ChatAdapter(ChatActivity mActivity, XmppService mXmppService,
			LinkedList<ChatMsgEntity> list) {
		mLayoutInflater = LayoutInflater.from(mActivity);
		this.list = list;
		this.mXmppService = mXmppService;
		this.mActivity = mActivity;
		mImageCacheParams = new ImageCacheParams(mActivity, "cache");
		mImageCache = ImageCache.getInstance(mImageCacheParams);
		mImageCache.initDiskCache();
	}

	@Override
	public int getViewTypeCount() {
		return 2;
	}

	@Override
	public int getCount() {
		return list.size();
	}

	@Override
	public Object getItem(int position) {
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public int getItemViewType(int position) {
		ChatMsgEntity entity = list.get(position);
		if (entity.getMsgSourse() == ChatMsgEntity.IS_COME_MSG) {
			return ChatMsgEntity.IS_COME_MSG;
		} else {
			return ChatMsgEntity.IS_SEND_MSG;
		}

	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// Debug.startMethodTracing("test");
		ChatMsgEntity entity = list.get(position);
		ViewHolder viewHolder = null;
		if (convertView == null) {
			if (entity.getMsgSourse() == ChatMsgEntity.IS_COME_MSG) {
				convertView = mLayoutInflater.inflate(
						R.layout.chatting_item_msg_text_left, null);
			} else {
				convertView = mLayoutInflater.inflate(
						R.layout.chatting_item_msg_text_right, null);
			}
			viewHolder = new ViewHolder();
			viewHolder.image = (ImageView) convertView
					.findViewById(R.id.tv_message_image);
			viewHolder.content = (TextView) convertView
					.findViewById(R.id.tv_message_chatcontent);
			viewHolder.headImage = (ImageView) convertView
					.findViewById(R.id.iv_message_userhead);
			viewHolder.playBtn = (ImageView) convertView
					.findViewById(R.id.voice_display_voice_play);
			viewHolder.sendTime = (TextView) convertView
					.findViewById(R.id.tv_message_sendtime);
			viewHolder.timeLayout = (LinearLayout) convertView
					.findViewById(R.id.ll_message_timelayout);
			viewHolder.voiceLayout = (RelativeLayout) convertView
					.findViewById(R.id.voice_display_voice_layout);
			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) convertView.getTag();
		}
		viewHolder.content.setTag(entity);
		viewHolder.content.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				ChatMsgEntity entity = (ChatMsgEntity) v.getTag();
				// 点击重新发送发送失败的消息
				if (entity.getMsgType() == ChatMsgEntity.COMMON_MESSAGE
						&& entity.getIsSended() == ChatMsgEntity.SENDED_FAILED) {
					try {
						mXmppService.sendChatMessage(entity);
						entity.setIsSended(ChatMsgEntity.SENDED_SUCCESS);
						ChatActivity.updateOrAddAdapterData(list, entity);
					} catch (XMPPException e) {
						entity.setIsSended(ChatMsgEntity.SENDED_FAILED);
						ChatActivity.updateOrAddAdapterData(list, entity);
						e.printStackTrace();
					} finally {
						notifyDataSetChanged();
					}
				}
			}
		});
		viewHolder.voiceLayout.setVisibility(View.GONE);
		viewHolder.content.setVisibility(View.GONE);
		viewHolder.image.setVisibility(View.GONE);
		switch (entity.getMsgType()) {
		case ChatMsgEntity.COMMON_MESSAGE:
			viewHolder.content.setVisibility(View.VISIBLE);
			if (entity.getMessage() != null) {
				SpannableString spannableString = FaceConversionUtil
						.getInstace().getExpressionString(mActivity,
								entity.getMessage());
				viewHolder.content.setText(spannableString);
			}
			break;
		case ChatMsgEntity.RECORD_FILE:
			switch (entity.getMsgSourse()) {
			case ChatMsgEntity.IS_COME_MSG:
				if (entity.getVoicePlayStatus() == ChatMsgEntity.PLAY_ING) {
					viewHolder.playBtn.setImageDrawable(mActivity
							.getResources().getDrawable(
									R.drawable.globle_player_btn_stop));
				} else {
					viewHolder.playBtn.setImageDrawable(mActivity
							.getResources().getDrawable(
									R.drawable.globle_player_btn_play_left));
				}
				break;
			case ChatMsgEntity.IS_SEND_MSG:
				if (entity.getVoicePlayStatus() == ChatMsgEntity.PLAY_ING) {
					viewHolder.playBtn.setImageDrawable(mActivity
							.getResources().getDrawable(
									R.drawable.globle_player_btn_stop));
				} else {
					viewHolder.playBtn.setImageDrawable(mActivity
							.getResources().getDrawable(
									R.drawable.globle_player_btn_play_right));
				}
				break;

			default:
				break;
			}
			viewHolder.playBtn.setImageDrawable(mActivity.getResources()
					.getDrawable(R.drawable.globle_player_btn_play_left));
			viewHolder.voiceLayout.setVisibility(View.VISIBLE);
			viewHolder.voiceLayout.setTag(entity);
			viewHolder.voiceLayout.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					// 点击录音
					ChatMsgEntity entity = (ChatMsgEntity) v.getTag();
					// 发送成功，点击则播放声音
					// if (entity.isSended == ChatMsgEntity.SENDED_SUCCESS)
					// {
					entity.setVoicePlayStatus(ChatMsgEntity.PLAY_ING);
					mActivity.playVoice(entity);
					notifyDataSetChanged();
					// }
					// else {
					// mSendMessageQueue.putEntity(entity);
					// }
				}
			});
			break;
		case ChatMsgEntity.IAMGE_FILE:
			viewHolder.image.setVisibility(View.VISIBLE);
			// viewHolder.image.setImageDrawable(mActivity.getResources()
			// .getDrawable(R.drawable.abaose));
			loadBitmap(entity.getPath(), viewHolder.image);
			viewHolder.image.setTag(entity);
			viewHolder.image.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					// 点击图片显示效果
					ChatMsgEntity entity = (ChatMsgEntity) v.getTag();
					if (entity.getIsSended() == ChatMsgEntity.SENDED_SUCCESS) {
						// 发送成功，点击则查看原图
					} else {
						// 发送失败，点击则重新发送
						mActivity.mSendMessageQueue.putEntity(entity);
					}
				}
			});
			break;
		default:
			break;
		}
//		 Debug.stopMethodTracing();
		return convertView;
	}

	class ViewHolder {
		ImageView headImage;
		ImageView image;
		TextView content;
		RelativeLayout voiceLayout;
		ImageView playBtn;
		TextView sendTime;
		LinearLayout timeLayout;
	}

	private void loadBitmap(String path, ImageView imageView) {
//		Debug.startMethodTracing("test");
		if (path == null) {
			return;
		}
		// final String imageKey = path;
		BitmapDrawable bitmap = mImageCache.getBitmapFromMemCache(path);
		if (bitmap != null) {
			imageView.setImageDrawable(bitmap);
			L.i(tag, "内存缓冲");
		} else {
			if (cancelPotentialWork(path, imageView)) {
				Bitmap bitmap1 = BitmapFactory.decodeResource(
						mActivity.getResources(), R.drawable.abaose);
				BitmapWorkerTask task = new BitmapWorkerTask(imageView);
				AsyncDrawable drawable = new AsyncDrawable(
						mActivity.getResources(), bitmap1, task);
				imageView.setImageDrawable(drawable);
				task.execute(path);

			}
		}
//		Debug.stopMethodTracing();
	}

	private static class AsyncDrawable extends BitmapDrawable {
		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

		public AsyncDrawable(final Resources res, final Bitmap bitmap,
				final BitmapWorkerTask bitmapWorkerTask) {
			super(res, bitmap);
			bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
					bitmapWorkerTask);
		}

		public BitmapWorkerTask getBitmapWorkerTask() {
			return bitmapWorkerTaskReference.get();
		}
	}

	/**
	 * 
	 * 图片处理AsyncTask
	 * 
	 * @author YINENG
	 *
	 */
	class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
		private final WeakReference<ImageView> imageViewReference;
		private String path = "";

		public BitmapWorkerTask(ImageView imageView) {
			// Use a WeakReference to ensure the ImageView can be garbage
			// collected
			imageViewReference = new WeakReference<ImageView>(imageView);
		}

		// Decode image in background.
		@Override
		protected Bitmap doInBackground(String... params) {
			path = params[0];
			Bitmap bitmap = mImageCache.getBitmapFromDiskCache(path);

			if (bitmap == null) {
				bitmap = ImageUtil.decodeSampledBitmapFromResource(params[0],
						100, 100);
				L.i(tag, "重新制作缩略图");
				mImageCache.addBitmapToCache(path,
						new BitmapDrawable(mActivity.getResources(), bitmap));
			} else {
				L.i(tag, "磁盘缓冲");
			}
			return bitmap;
		}

		// Once complete, see if ImageView is still around and set bitmap.
		@Override
		protected void onPostExecute(Bitmap bitmap) {
			if (isCancelled()) {
				bitmap = null;
			}

			if (imageViewReference != null && bitmap != null) {
				final ImageView imageView = imageViewReference.get();
				final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
				if (this == bitmapWorkerTask && imageView != null) {
					imageView.setImageBitmap(bitmap);
				}
			}
		}
	}

	/**
	 * 检查确保了另外一个在跑的任务已经在ImageView视图中。 如果是这样，它通过执行 cancel() 方法来取消之前的一个任务.
	 *
	 * @param path
	 * @param imageView
	 * @return
	 */
	private static boolean cancelPotentialWork(String path, ImageView imageView) {
		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

		if (bitmapWorkerTask != null) {
			final String tempPath = bitmapWorkerTask.path;
			// If bitmapData is not yet set or it differs from the new data
			if (tempPath == null || !tempPath.equals(path)) {
				// Cancel previous task
				bitmapWorkerTask.cancel(true);
			} else {
				// The same work is already in progress
				return false;
			}
		}
		// No task associated with the ImageView, or an existing task was
		// cancelled
		return true;
	}

	/**
	 * 
	 * 从ImageView中的AsyncDrawable获得对应处理图片的线程
	 * 
	 * @param imageView
	 * @return
	 */
	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
		if (imageView != null) {
			final Drawable drawable = imageView.getDrawable();
			if (drawable instanceof AsyncDrawable) {
				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
				return asyncDrawable.getBitmapWorkerTask();
			}
		}
		return null;
	}

}
